package initialize

import (
	"sync"
	"transfer-service/internal/conf"
	"transfer-service/internal/global"

	mqtt "github.com/eclipse/paho.mqtt.golang"
	"github.com/hashicorp/go-uuid"
)

func InitMQTTClient(conf *conf.Bootstrap) {
	// 初始化MQTTList
	global.MQTTList = &sync.Map{}
	InitGovNetMqttClient(conf)
	InitVideoNetMqttClient(conf)
}

// InitGovNetMqttClient 初始化 政务MQTT 客户端
func InitGovNetMqttClient(conf *conf.Bootstrap) {
	config := conf.GetMiddleware().GetMqtt()
	c := config.GovNet
	generateUUID, err := uuid.GenerateUUID()
	if err != nil {
		panic(err)
	}
	opts := mqtt.NewClientOptions()
	opts.AddBroker(c.GetAddress())
	opts.SetClientID(generateUUID)
	opts.SetUsername(c.GetUsername())
	opts.SetPassword(c.GetPassword())
	opts.SetAutoReconnect(c.GetAutoReconnect())   // 自动重连
	opts.SetCleanSession(c.GetCleanSession())     // 保持会话
	opts.SetDefaultPublishHandler(messageHandler) // 默认消息处理器
	opts.SetConnectRetry(true)
	opts.SetConnectTimeout(c.GetConnectTimeout().AsDuration()) // 连接超时时间
	opts.SetKeepAlive(c.GetKeepAlive().AsDuration())           // 心跳间隔
	opts.SetResumeSubs(c.GetResumeSubs())
	// 设置连接处理器
	opts.OnConnect = connectHandler
	// 设置连接丢失处理器- 恢复订阅
	opts.OnConnectionLost = connectLostHandler
	// 创建客户端
	client := mqtt.NewClient(opts)

	// 连接到 MQTT 代理
	token := client.Connect()
	if !token.WaitTimeout(c.GetConnectTimeout().AsDuration()) {
		panic("mqtt connect timeout")
	}
	if token.Error() != nil {
		panic(token.Error())
	}

	// 设置全局 MQTT 客户端
	global.MQTTList.Store(c.GetAddress(), client)
	global.LOG.Infof("MQTT 连接成功: %s", c.GetClientId())
}

// InitVideoNetMqttClient 初始化 视频网MQTT 客户端
func InitVideoNetMqttClient(conf *conf.Bootstrap) {
	config := conf.GetMiddleware().GetMqtt()
	c := config.VideoNet
	generateUUID, err := uuid.GenerateUUID()
	if err != nil {
		panic(err)
	}
	opts := mqtt.NewClientOptions()
	opts.AddBroker(c.GetAddress())
	opts.SetClientID(generateUUID)
	opts.SetUsername(c.GetUsername())
	opts.SetPassword(c.GetPassword())
	opts.SetAutoReconnect(c.GetAutoReconnect())   // 自动重连
	opts.SetCleanSession(c.GetCleanSession())     // 保持会话
	opts.SetDefaultPublishHandler(messageHandler) // 默认消息处理器
	opts.SetConnectRetry(true)
	opts.SetConnectTimeout(c.GetConnectTimeout().AsDuration()) // 连接超时时间
	opts.SetKeepAlive(c.GetKeepAlive().AsDuration())           // 心跳间隔
	opts.SetResumeSubs(c.GetResumeSubs())
	// 设置连接处理器
	opts.OnConnect = connectHandler
	// 设置连接丢失处理器
	opts.OnConnectionLost = connectLostHandler
	// 创建客户端
	client := mqtt.NewClient(opts)

	// 连接到 MQTT 代理
	token := client.Connect()
	if !token.WaitTimeout(c.GetConnectTimeout().AsDuration()) {
		panic("mqtt connect timeout")
	}
	if token.Error() != nil {
		panic(token.Error())
	}

	// 设置全局 MQTT 客户端
	global.MQTTList.Store(c.GetAddress(), client)
	global.LOG.Infof("MQTT 连接成功: %s", c.GetClientId())
}

// connectLostHandler 连接丢失处理器
func connectLostHandler(client mqtt.Client, err error) {
	// 获取 OptionsReader 的返回值
	optionsReader := client.OptionsReader()
	// 获取 ClientID
	clientID := optionsReader.ClientID()
	// 这里可以做一些恢复连接的操作或者记录丢失的日志
	global.LOG.Errorf("MQTT 连接丢失: %v, clinetId:%v", err, clientID)
	// 可以选择重连的逻辑，具体取决于需求
	// 将客户端添加到全局列表中
	global.LOG.Infof("MQTT <Host>: %v", optionsReader.Servers()[0].Host)
	global.MQTTList.Store(optionsReader.Servers()[0].Host, client)
	global.LOG.Infof("clientId: %s,MQTT 重连成功", clientID)
}

// connectHandler 连接成功处理器
func connectHandler(client mqtt.Client) {
	optionsReader := client.OptionsReader()
	global.LOG.Infof("MQTT <Host>: %v", optionsReader.Servers()[0].Host)
}

// messageHandler 默认的消息处理函数
func messageHandler(client mqtt.Client, msg mqtt.Message) {
	// 打印收到的消息主题和内容
	global.LOG.Infof("收到消息: %s 主题: %s", msg.Payload(), msg.Topic())
}
